package admin

import (
	"exercise/application/yiran/app/libs"
	"exercise/application/yiran/app/model"
	"exercise/application/yiran/app/request/adminRequest"
	"fmt"
	"github.com/gin-gonic/gin"
	"strings"
)

type enrollRuleService struct {
	ctx *gin.Context
}

// List 列表
func (rcv *enrollRuleService) List(request *adminRequest.EnrollRuleListRequest) (map[string]interface{}, error) {
	schoolId, _ := rcv.ctx.Get("schoolId")
	list := make([]model.EnrollRule, 0)
	paging := model.Paging{}
	paging.Page = request.Page
	paging.PageSize = request.PageSize

	total, err := model.NewDb("").FindAllAndCount(&list, "school_id = ? ", []interface{}{schoolId}, model.OrderOrGroup{}, paging, []string{})

	if err != nil {
		return nil, fmt.Errorf("暂无数据：%w", err)
	}

	return map[string]interface{}{
		"list":  list,
		"total": total,
	}, err
}

// Add 新增
func (rcv *enrollRuleService) Add(request *adminRequest.AddEnrollRuleRequest) (id int64, err error) {

	schoolId, _ := rcv.ctx.Get("schoolId")
	rule := new(model.EnrollRule)

	rule.Year = request.Year
	rule.TypeId = request.TypeId
	rule.SchoolId = schoolId.(int64)
	rule.LqName = request.LqName
	rule.LqRange = request.LqRange
	rule.LqField = request.LqField
	rule.LqType = request.LqType
	rule.TjType = request.TjType
	rule.CreateTime = libs.CurrentTime()

	err = model.NewDb("").InsertRecord(rule)
	if err != nil {
		return id, err
	}

	return rule.Id, nil
}

// Edit 编辑
func (rcv *enrollRuleService) Edit(request *adminRequest.EditEnrollRuleRequest) error {
	rule := new(model.EnrollRule)
	err := model.NewDb("").FindOne(rule, "id = ? ", []interface{}{request.Id}, "*", []string{})
	if err != nil {
		return err
	}

	rule.Year = request.Year
	rule.TypeId = request.TypeId
	rule.LqName = request.LqName
	rule.LqRange = request.LqRange
	rule.LqField = request.LqField
	rule.LqType = request.LqType
	rule.TjType = request.TjType

	err = model.NewDb("").SaveRecord(rule)
	if err != nil {
		return err
	}
	return nil
}

// Detail 详情
func (rcv *enrollRuleService) Detail() (res interface{}, err error) {
	id := rcv.ctx.Param("id")
	rule := new(model.EnrollRule)
	detail := make(map[string]interface{}, 0)
	err = model.NewDb("").FindOneMap(rule, "id = ?", []interface{}{id}, "id,lq_name,lq_range,lq_field,lq_type,pid,tj_type", &detail)

	if err != nil {
		return nil, err
	}

	sql, where := rcv.GetLqRangeStudent(detail["lq_range"].(string))

	ret := make(map[string]interface{}, 0)
	ret["sql"] = sql
	ret["where"] = where
	ret["detail"] = detail
	return ret, err
}

// Deleted 删除
func (rcv *enrollRuleService) Deleted() error {
	id := rcv.ctx.Param("id")
	rule := new(model.EnrollRule)
	err := model.NewDb("").DeleteRecord(rule, "id = ?", []interface{}{id})
	return err
}

// GetLqRangeStudent 获取计算的学生范围
func (rcv *enrollRuleService) GetLqRangeStudent(lqRange string) (sql string, where []interface{}) {
	where = make([]interface{}, 0)
	if lqRange != "" {
		stuRange := make(map[string]interface{}, 0)
		libs.JsonDecode([]byte(lqRange), &stuRange)
		for k, v := range stuRange {
			if libs.IsSlice(v) { //参数是切片
				vv := v.([]interface{})[0]
				op := strings.ToUpper(v.([]interface{})[1].(string))

				sql += k + " " + op + " ? AND "
				//判断是否存在in查询
				if strings.Contains(op, "IN") {
					where = append(where, strings.Split(vv.(string), ","))
				}
				//判断是否存在like
				if strings.Contains(op, "LIKE") {
					where = append(where, "%"+vv.(string)+"%")
				}
				continue
			}

			sql += k + " = ? AND "
			where = append(where, v)
		}
	}

	return strings.TrimRight(sql, " AND "), where
}

// GetLqStudentOrderRule 录取学生的排序规则,一般都是按照某课成绩排序的
func (rcv *enrollRuleService) GetLqStudentOrderRule(rule string) (sql string) {
	if rule != "" {
		jsRule := make(map[string]interface{}, 0)
		libs.JsonDecode([]byte(rule), &jsRule)

		for k, r := range jsRule {
			s := ""
			for kk, vv := range r.(map[string]interface{}) {
				s += "`" + kk + "` * " + libs.Float64String(vv.(float64), 2) + " + "
			}
			sql += "`" + k + "` = " + "(" + strings.TrimRight(s, " + ") + "),"
		}
	}
	return strings.TrimRight(sql, ",")
}

// GetRankSort 获取排序规则
func (rcv *enrollRuleService) GetRankSort(rankSort string) string {
	orderBy := ""
	rank := strings.Split(rankSort, ",")
	for _, s := range rank {
		orderBy += s + " DESC,"
	}
	return strings.TrimRight(orderBy, ",")
}

func NewEnrollRuleService(c *gin.Context) *enrollRuleService {
	return &enrollRuleService{
		ctx: c,
	}
}
